//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <elatypes.h>

EXTERN_C UInt32 save_flags_cli();
EXTERN_C void restore_flags(UInt32);
EXTERN_C Int32 sys_cmpxchg(PInt32, Int32, Int32);

/*
 * The InterlockedIncrement function both increments (increases by one)
 * the value of the specified 32-bit variable and checks the resulting value.
 * InterlockedIncrement prevents more than one thread from using
 * the InterlockedDecrement or InterlockedIncrement function to
 * access the same variable simultaneously.
 *
 * defined in llocre.asm
 */
EXTERN_C Int32 InterlockedIncrement(PInt32 pAddend);

/*
 * The InterlockedDecrement function both decrements (decreases by one)
 * the value of the specified 32-bit variable and checks the resulting value.
 * InterlockedDecrement prevents more than one thread from using
 * the InterlockedDecrement or InterlockedIncrement function to
 * access the same variable simultaneously.
 *
 * defined in llocre.asm
 */
EXTERN_C Int32 InterlockedDecrement(PInt32 pAddend);

/*
 * The InterlockExchangeAdd function performs an atomic addition of
 * an increment value to an addend variable. The function prevents
 * more than one thread from using the same variable simultaneously.
 *
 * defined in llocre.asm
 */
EXTERN_C Int32 InterlockedExchangeAdd(PInt32 pAddend, Int32 increment);

/*
 * The InterlockedExchange function atomically exchanges
 * a pair of 32-bit values.  The prior value of the Int32 value
 * pointed to by Target indicates success.
 *
 * defined in llocre.asm
 */
EXTERN_C Int32 InterlockedExchange(PInt32 pTarget, Int32 value);

/*
 * The InterlockedExchangePointer function atomically exchanges
 * a pair of values. The function prevents more than one thread
 * from using the same variable simultaneously.
 *
 * If you are exchanging pointer values, this function supersedes
 * the InterlockedExchange function.
 */
PVoid InterlockedExchangePointer(PVoid * pTarget, PVoid value)
{
    return (PVoid)InterlockedExchange((PInt32)pTarget, (Int32)value);
}

/*
 * The InterlockedCompareExchange function performs an atomic comparison
 * of the specified values and exchanges the values, based on the outcome
 * of the comparison. The function prevents more than one thread from
 * using the same variable simultaneously.
 *
 * If you are exchanging pointer values, this function has been superseded
 * by the InterlockedCompareExchangePointer function.
 */
EXTERN_C Int32 InterlockedCompareExchange(
        PInt32 destination, Int32 exchange, Int32 comperand);

/*
 * The InterlockedCompareExchangeEx is another version of
 * InterlockedCompareExchange only for the mutex.cpp
 */
Int32 InterlockedCompareExchangeEx(
    PInt32 destination, Int32 exchange, Int32 comperand)
{
    return sys_cmpxchg(destination, exchange, comperand);
}

/*
 * The InterlockedCompareExchangePointer function performs an atomic
 * comparison of the specified values parameters and exchanges the
 * values, based on the outcome of the comparison. More than one
 * thread cannot use the same variable simultaneously.
 *
 * If you are exchanging pointer values, this function supersedes
 * the InterlockedCompareExchange function.
 */
PVoid InterlockedCompareExchangePointer(
    PVoid * pDestination, PVoid exchange, PVoid comperand)
{
    return (PVoid)InterlockedCompareExchange(
                    (PInt32)pDestination, (Int32)exchange, (Int32)comperand);
}
